package dproxy.application.ui.commands;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;

import dproxy.application.ui.CommandLineProcessor;
import dproxy.server.cache.bo.CacheBO;
import dproxy.server.cache.to.RequestResponse;
import dproxy.server.common.exceptions.AppInfrastructureException;

/**
 * Export a request for user edition
 * Usage:
 * export index X
 * TODO [3] New command: export database / import database : dumps the whole data to a file
 */
public class Export implements Command {

	public static final String BASE_NAME = "entry_";
	public static final String EXTENSION = ".data";
	
	public static final String KEY = "key_";
	public static final String REQUEST = "request_";
	public static final String RESPONSE = "response";
	
	/** Sub command (command option). */
	private String subCommand;

	/** Number numeric parameter. */
	private int firstNumberParameter;

	/** Sub-Command that will export a determined entry. */
	private static final String SC_INDEX = "index";

	/**
	 * @see dproxy.application.ui.commands.Command#description()
	 */
	public String description() {
		return "   'export'     - Exports a request for user editting\n"
				+ "                  - Options:\n" + "                    "
				+ SC_INDEX + " N      - exports an entry with specified index\n";
	}

	/**
	 * @see dproxy.application.ui.commands.Command#validate(Collection)
	 */
	public void validate(Collection<String> parameters)
			throws ValidationException {
		Iterator<String> itParameters = parameters.iterator();
		if (itParameters.hasNext()) {
			subCommand = itParameters.next();
			if (SC_INDEX.equals(subCommand)) {
				firstNumberParameter = ValidationUtils.getNumberParameter(itParameters);
				ValidationUtils.validateNoMoreParameters(itParameters);
			} else {
				throw new ValidationException();
			}
		} else {
			throw new ValidationException();
		}

	}

	/**
	 * @see dproxy.application.ui.commands.Command#confirm()
	 */
	public boolean confirm() {
		// No need for confirmation:
		return true;
	}

	/**
	 * @see dproxy.application.ui.commands.Command#execute()
	 */
	public void execute() {
		FileOutputStream osRequestKey = null;
		FileOutputStream osRequest = null;
		FileOutputStream osResponse = null;
		
		try {
			if (SC_INDEX.equals(subCommand)) {
				RequestResponse rr = CacheBO.getInstance()
						.findByIndex(firstNumberParameter);
				if (rr != null) {
					
					String nameRequestKey = BASE_NAME + KEY + rr.getIndex() + EXTENSION;
					String nameRequest = BASE_NAME + REQUEST + rr.getIndex() + EXTENSION;
					String nameResponse = BASE_NAME + RESPONSE + rr.getIndex() + EXTENSION;
					
					osRequestKey = new FileOutputStream(nameRequestKey);
					osRequest = new FileOutputStream(nameRequest);
					osResponse = new FileOutputStream(nameResponse);
					
					osRequestKey.write(rr.getKey().getBytes());
					osRequest.write(rr.getRequestContents());
					osResponse.write(rr.getResponseContents());
					
					CommandLineProcessor.getInstance().write(
							"Entry successfully exported to files : " + nameRequestKey
							+ ", " + nameRequest + " and " + nameResponse);
				} else {
					CommandLineProcessor.getInstance().write("Entry not found");
				}
			}
		} catch (IOException e) {
			throw new AppInfrastructureException(e);
		} finally {
			if (osRequestKey != null) {
				try {
					osRequestKey.close();
				} catch (IOException e) {
					CommandLineProcessor.getInstance().write("Error closing file" + e);
				}
			}
			if (osRequest != null) {
				try {
					osRequest.close();
				} catch (IOException e) {
					CommandLineProcessor.getInstance().write("Error closing file" + e);
				}
			}
			if (osResponse != null) {
				try {
					osResponse.close();
				} catch (IOException e) {
					CommandLineProcessor.getInstance().write("Error closing file" + e);
				}
			}
		}
	}

}
